Running into errors and exceptions is inevitable, and debugging is a huge part of modern-day product development. As of now, we've worked with the roots of Python syntax, and have encountered many types of errors that are built-in. Of course, as you proceed, you will pass more complex errors. Let's see how it's done.
Before explaining what an Exception is, let's look at a quick syntax error.
In [1]:
# Producing an Error
print("hey there)
What if we wanted to prevent this error from stopping our program? For that case, we use what's called try-except statements. Here's the general syntax.
try:
// possible error inducing code
except Error:
// handle the error
except AnotherError:
// you can handle more than 1 error
else:
// if no exception runs
finally:
// run no matter what
This is the full syntax of try-except. We don't even need else or finally statements. However, we will use them after these basic examples.
Example 1 Let's try catching a divide by 0 error.
In [14]:
# Catching a SyntaxError
try:
print(8/0)
except ZeroDivisionError:
print("There is no dividing by 0")
Example 2 What if try sending in a string as a float?
In [15]:
try:
user_input = float("Is this a float?")
except ValueError:
print("Put a number in there, man!")
Let's quickly go over else and finally. Recall, the else block will run if no exception runs, and the finally will always run.
Example 3 Catching a TypeErrror (trying to mutate a string type - recall these sequences are immutable)
In [24]:
# Mutation of a String?
try:
my_str = "hello"
my_str[1] = "tr"
except TypeError:
print("We've got a TypeError")
else:
print("This shouldn't run!")
finally:
print("Finally, I always print!")
Let's look at some other features.
You can check for more than one exception! Now, it's important to understand that except block will only handle the first exception it finds. Order them in a tuple!
One thing we have not discussed is that as soon as
In [31]:
# Broadening the except statement
try:
str[0] == "h"
except (TypeError, SyntaxError):
print("String mutate")
In [36]:
# Trying to exce
try:
print(4/0)
str[1] = "e"
except (ZeroDivisionError, TypeError):
print("what!")
The last except (or the only one, if there's only one) doesn't need an Exception associated with it. It's know as the "default except".
In [39]:
try:
print(4/0)
except:
print("wow")
In [41]:
# Catching the error in its respective statement
try:
print(4/0)
except ZeroDivisionError:
print("ZeroDiv Error")
except:
print("There's an error, I just don't know what!")
else:
print("There wasn't an error!")
In [42]:
# Catching the error in the deault, if the specific except fails
try:
str[4] = "wow"
except ZeroDivisionError:
print("ZeroDiv Error")
except:
print("There's an error, I just don't know what!")
else:
print("There wasn't an error!")
Sometimes, you may need to physically raise your own errors. This is possible with the raise keyword. It works as expected.
In [44]:
try:
raise TypeError
except TypeError:
print("Error raised")
In [51]:
class MyException(Exception):
def __init__(self, result):
self.result = result
def __str__(self):
return "MyException occured, result that caused it: {}".format(self.result)
Below, we'll catch it, and treat it with "as" to shorten the name and not cause the statement to confuse MyException.
In [55]:
try:
raise MyException("error string")
except MyException as myexcep:
print(myexcep)